package org.tinygame.herostory.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinygame.herostory.MainThreadProcessor;

import java.text.MessageFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author anan
 * @create 2022-05-07 20:00
 */
public class AsyncOperationProcessor {

    static private final Logger LOGGER = LoggerFactory.getLogger(AsyncOperationProcessor.class);


    /**
     * 单例对象
     */

    static private final AsyncOperationProcessor _instance = new AsyncOperationProcessor();

    /**
     * 获取单例对象
     */

    static public AsyncOperationProcessor getInstance(){ return _instance; }

    private final ExecutorService[] _esArray = new ExecutorService[8];

    /**
     * 私有化构造方法
     */

    private AsyncOperationProcessor(){
        for (int i = 0; i < _esArray.length; i++) {

            final String threadName = MessageFormat.format("AsyncOperationProcessor[ {0} ]", i);

            _esArray[i] = Executors.newSingleThreadExecutor(newRunnable -> {
                Thread newThread = new Thread(newRunnable);
                newThread.setName(threadName);
                return newThread;
            });

        }
    }

    public void process(IAsyncOperation op){
        if(null == op) return;

        int bindId = Math.abs(op.getBindId());
        int esIndex = bindId % _esArray.length;

        _esArray[esIndex].submit(() -> {
            /**
             * 因为doAsync和doFinish是在一个线程内执行的，因此是串行，必须在doAsync执行结束后执行doFinish,因此保证了数据的一致性
             */try {
                op.doAsync();

                MainThreadProcessor.getInstance().process(op::doFinish);
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        });


    }





}
